package com.kly.sc.api.application.controller.user;

import com.fqgj.base.services.redis.RedisClient;
import com.fqgj.common.api.Response;
import com.fqgj.common.api.annotations.ParamsValidate;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.google.common.collect.Lists;
import com.kly.sc.api.application.consts.Constants;
import com.kly.sc.api.application.controller.user.request.AddBehaviorRequest;
import com.kly.sc.api.application.helper.RequestLocalInfo;
import com.kly.sc.api.application.service.utils.BaseComponent;
import com.kly.sc.api.application.utils.RpcUtils;
import com.kly.sc.api.infras.exception.ApplicationException;
import com.kly.user.constant.RedisKey;
import com.kly.user.dto.UserBehaviorReq;
import com.kly.user.dto.UserInfoDto;
import com.kly.user.enums.LogActionEnum;
import com.kly.user.enums.LogResultTypeEnum;
import com.kly.user.service.BehaviorService;
import com.kly.user.service.UserService;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * @author linqu
 */
@RestController
@RequestMapping("/api/behavior")
public class UserBehaviorController extends BaseComponent {

    private static final Log logger = LogFactory.getLog(UserBehaviorController.class);

    @Resource
    RedisClient redisClient;

    @Resource
    BehaviorService behaviorService;
    @Resource
    UserService userService;

    private static final Integer ZERO = 0;


    /**
     * 添加用户行为数据
     *
     * @param addBehaviorRequest
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/doLog")
    @ParamsValidate
    public Response doLog(@RequestBody AddBehaviorRequest addBehaviorRequest) {


        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        final UserInfoDto userInfo = RpcUtils.getResult(userService.getUserByUserCode(userCode));
        if (Objects.isNull(userInfo)) {
            throw new ApplicationException("User not exists!");
        }


        // 添加用户操作记录信息
        final UserBehaviorReq userBehaviorReq = getUserBehaviorReq(addBehaviorRequest, userCode);
        final Response response = behaviorService.doAction(userBehaviorReq);

        // 缓存被pass掉的用户
        if (Objects.nonNull(response) && response.isSuccess()) {
            cacheUserLogs(addBehaviorRequest, userCode, userInfo.getLookingFor());
        }
        return Response.ok();
    }

    /**
     * 缓存部分用户行为
     *
     * @param addBehaviorRequest 用户行为
     */
    private void cacheUserLogs(AddBehaviorRequest addBehaviorRequest, String userCode, Integer lookingFor) {
        try {
            if (LogActionEnum.BROSE_IMAGES.getType() == addBehaviorRequest.getActionType()
                    && LogResultTypeEnum.PASS.getType() == addBehaviorRequest.getResultType()) {
                if (StringUtils.isEmpty(addBehaviorRequest.getUserCodeOperated())) {
                    throw new ApplicationException("The userCodeOperated should not be empty!");
                }
                final Set<String> likeUsers = redisClient.sMembers(RedisKey.WLM_PASS, userCode, String.valueOf(lookingFor));
                redisClient.sAdd(RedisKey.WLM_PASS, addBehaviorRequest.getUserCodeOperated(), userCode, String.valueOf(lookingFor));
                if (CollectionUtils.isEmpty(likeUsers)) {
                    redisClient.expire(RedisKey.WLM_PASS, Constants.EFFECTIVE_IN_72_HOURS, userCode, String.valueOf(lookingFor));
                }
            }
        } catch (ApplicationException e) {
            logger.error("Add like or disLike failed, userCode={}", userCode);
        }

    }



    /**
     * 组装请求参数
     *
     * @param addBehaviorRequest
     * @return
     */
    private UserBehaviorReq getUserBehaviorReq(@RequestBody AddBehaviorRequest addBehaviorRequest, String userCode) {
        return UserBehaviorReq.builder().userCode(userCode)
                .userCodeOperated(addBehaviorRequest.getUserCodeOperated()).actionType(addBehaviorRequest.getActionType())
                .actionDetail(addBehaviorRequest.getActionDetail()).resultType(addBehaviorRequest.getResultType()).build();
    }

}
